﻿using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Threading;

namespace Sustainalytics.ReportGenerator.BL
{
    [EventSource(Name = "Sustainalytics-PdfGenerationService")]
    public sealed class PdfGenerationEventSource : EventSource, ILogPdf
    {
        private static Lazy<PdfGenerationEventSource> _lazy = new Lazy<PdfGenerationEventSource>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);

        private PdfGenerationEventSource()
        {
        }

        public static PdfGenerationEventSource Log
        {
            get { return _lazy.Value; }
        }

        [NonEvent]
        private static PdfGenerationEventSource InitLog()
        {
            var log = new PdfGenerationEventSource();
            log.Ping();

            return log;
        }

        [Event(1, Level = EventLevel.LogAlways)]
        private void Ping()
        {
            if (IsEnabled())
            {
                WriteEvent(1);
            }
        }

        [NonEvent]
        public void LogError(Exception ex)
        {
            if (IsEnabled())
            {
                WriteEvent(3, ex.ToString());
            }
        }

        [Event(3, Level = EventLevel.Error)]
        public void LogError(string ex)
        {
            if (IsEnabled())
            {
                WriteEvent(3, ex);
            }
        }

        [Event(6, Level = EventLevel.Informational)]
        public void LogNullPdfRequest(string msg)
        {
            if (!IsEnabled()) return;
            WriteEvent(6, msg);
        }

        [Event(7, Level = EventLevel.Informational)]
        public void LogPdfRequestEmptyCompanies(string msg)
        {
            if (!IsEnabled()) return;
            WriteEvent(7, msg);
        }

        [Event(8, Level = EventLevel.Informational)]
        public void LogPdfGeneration(string msg)
        {
            if (!IsEnabled()) return;
            WriteEvent(8, msg);
        }

        public void LogGenerationData(string msg)
        {
            LogPdfGeneration(msg);
        }

        [Event(9, Level = EventLevel.Informational)]
        public void CancelGeneration(string msg)
        {
            if (!IsEnabled()) return;
            WriteEvent(9, msg);
        }
    }

    public interface ILogPdf
    {
        void LogGenerationData(string msg);
    }

    public class LogDebug : ILogPdf
    {
        private static Lazy<LogDebug> _lazy = new Lazy<LogDebug>(() => new LogDebug(), LazyThreadSafetyMode.ExecutionAndPublication);

        public static LogDebug Log
        {
            get { return _lazy.Value; }
        }

        private LogDebug()
        {
        }

        public void LogGenerationData(string msg)
        {
            Debug.WriteLine(msg);
        }
    }

    public class LogAggregator
    {
        private readonly ILogPdf[] _logs;

        public LogAggregator(ILogPdf[] logs)
        {
            _logs = logs;
        }

        public void Log(string msg)
        {
            foreach (var logPdf in _logs)
            {
                logPdf.LogGenerationData(msg);
            }
        }
    }
}
